<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: Image Gradients</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="../../d5/d10/tutorial_js_root.html">OpenCV.js Tutorials</a></li><li class="navelem"><a class="el" href="../../d2/df0/tutorial_js_table_of_contents_imgproc.html">Image Processing</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Image Gradients </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h2>Goal </h2>
<ul>
<li>Find Image gradients, edges etc</li>
<li>We will learn following functions : <b><a class="el" href="../../d4/d86/group__imgproc__filter.html#gacea54f142e81b6758cb6f375ce782c8d" title="Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator...">cv.Sobel()</a></b>, <b><a class="el" href="../../d4/d86/group__imgproc__filter.html#gaa13106761eedf14798f37aa2d60404c9" title="Calculates the first x- or y- image derivative using Scharr operator. ">cv.Scharr()</a></b>, <b><a class="el" href="../../d4/d86/group__imgproc__filter.html#gad78703e4c8fe703d479c1860d76429e6" title="Calculates the Laplacian of an image. ">cv.Laplacian()</a></b> etc</li>
</ul>
<h2>Theory </h2>
<p>OpenCV provides three types of gradient filters or High-pass filters, Sobel, Scharr and Laplacian. We will see each one of them.</p>
<h3>1. Sobel and Scharr Derivatives</h3>
<p>Sobel operators is a joint Gausssian smoothing plus differentiation operation, so it is more resistant to noise. You can specify the direction of derivatives to be taken, vertical or horizontal (by the arguments, yorder and xorder respectively). You can also specify the size of kernel by the argument ksize. If ksize = -1, a 3x3 Scharr filter is used which gives better results than 3x3 Sobel filter. Please see the docs for kernels used.</p>
<p>We use the functions: <b><a class="el" href="../../d4/d86/group__imgproc__filter.html#gacea54f142e81b6758cb6f375ce782c8d" title="Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator...">cv.Sobel</a> (src, dst, ddepth, dx, dy, ksize = 3, scale = 1, delta = 0, borderType = <a class="el" href="../../d2/de8/group__core__array.html#gga209f2f4869e304c82d07739337eae7c5afe14c13a4ea8b8e3b3ef399013dbae01" title="same as BORDER_REFLECT_101 ">cv.BORDER_DEFAULT</a>)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src</td><td>input image. </td></tr>
    <tr><td class="paramname">dst</td><td>output image of the same size and the same number of channels as src. </td></tr>
    <tr><td class="paramname">ddepth</td><td>output image depth(see cv.combinations); in the case of 8-bit input images it will result in truncated derivatives. </td></tr>
    <tr><td class="paramname">dx</td><td>order of the derivative x. </td></tr>
    <tr><td class="paramname">dy</td><td>order of the derivative y. </td></tr>
    <tr><td class="paramname">ksize</td><td>size of the extended Sobel kernel; it must be 1, 3, 5, or 7. </td></tr>
    <tr><td class="paramname">scale</td><td>optional scale factor for the computed derivative values. </td></tr>
    <tr><td class="paramname">delta</td><td>optional delta value that is added to the results prior to storing them in dst. </td></tr>
    <tr><td class="paramname">borderType</td><td>pixel extrapolation method(see <a class="el" href="../../d2/de8/group__core__array.html#ga209f2f4869e304c82d07739337eae7c5">cv.BorderTypes</a>).</td></tr>
  </table>
  </dd>
</dl>
<p><b><a class="el" href="../../d4/d86/group__imgproc__filter.html#gaa13106761eedf14798f37aa2d60404c9" title="Calculates the first x- or y- image derivative using Scharr operator. ">cv.Scharr</a> (src, dst, ddepth, dx, dy, scale = 1, delta = 0, borderType = <a class="el" href="../../d2/de8/group__core__array.html#gga209f2f4869e304c82d07739337eae7c5afe14c13a4ea8b8e3b3ef399013dbae01" title="same as BORDER_REFLECT_101 ">cv.BORDER_DEFAULT</a>)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src</td><td>input image. </td></tr>
    <tr><td class="paramname">dst</td><td>output image of the same size and the same number of channels as src. </td></tr>
    <tr><td class="paramname">ddepth</td><td>output image depth(see cv.combinations). </td></tr>
    <tr><td class="paramname">dx</td><td>order of the derivative x. </td></tr>
    <tr><td class="paramname">dy</td><td>order of the derivative y. </td></tr>
    <tr><td class="paramname">scale</td><td>optional scale factor for the computed derivative values. </td></tr>
    <tr><td class="paramname">delta</td><td>optional delta value that is added to the results prior to storing them in dst. </td></tr>
    <tr><td class="paramname">borderType</td><td>pixel extrapolation method(see <a class="el" href="../../d2/de8/group__core__array.html#ga209f2f4869e304c82d07739337eae7c5">cv.BorderTypes</a>).</td></tr>
  </table>
  </dd>
</dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_gradients_Sobel.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
</p>
<h3>2. Laplacian Derivatives</h3>
<p>It calculates the Laplacian of the image given by the relation, \(\Delta src = \frac{\partial ^2{src}}{\partial x^2} + \frac{\partial ^2{src}}{\partial y^2}\) where each derivative is found using Sobel derivatives. If ksize = 1, then following kernel is used for filtering:</p>
<p class="formulaDsp">
\[kernel = \begin{bmatrix} 0 &amp; 1 &amp; 0 \\ 1 &amp; -4 &amp; 1 \\ 0 &amp; 1 &amp; 0 \end{bmatrix}\]
</p>
<p>We use the function: <b><a class="el" href="../../d4/d86/group__imgproc__filter.html#gad78703e4c8fe703d479c1860d76429e6" title="Calculates the Laplacian of an image. ">cv.Laplacian</a> (src, dst, ddepth, ksize = 1, scale = 1, delta = 0, borderType = <a class="el" href="../../d2/de8/group__core__array.html#gga209f2f4869e304c82d07739337eae7c5afe14c13a4ea8b8e3b3ef399013dbae01" title="same as BORDER_REFLECT_101 ">cv.BORDER_DEFAULT</a>)</b> </p><dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src</td><td>input image. </td></tr>
    <tr><td class="paramname">dst</td><td>output image of the same size and the same number of channels as src. </td></tr>
    <tr><td class="paramname">ddepth</td><td>output image depth. </td></tr>
    <tr><td class="paramname">ksize</td><td>aperture size used to compute the second-derivative filters. </td></tr>
    <tr><td class="paramname">scale</td><td>optional scale factor for the computed Laplacian values. </td></tr>
    <tr><td class="paramname">delta</td><td>optional delta value that is added to the results prior to storing them in dst. </td></tr>
    <tr><td class="paramname">borderType</td><td>pixel extrapolation method(see <a class="el" href="../../d2/de8/group__core__array.html#ga209f2f4869e304c82d07739337eae7c5">cv.BorderTypes</a>).</td></tr>
  </table>
  </dd>
</dl>
<h2>Try it </h2>
<p> 
<iframe src="../../js_gradients_Laplacian.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
</p>
<h2>One Important Matter! </h2>
<p>In our last example, output datatype is cv.CV_8U. But there is a slight problem with that. Black-to-White transition is taken as Positive slope (it has a positive value) while White-to-Black transition is taken as a Negative slope (It has negative value). So when you convert data to cv.CV_8U, all negative slopes are made zero. In simple words, you miss that edge.</p>
<p>If you want to detect both edges, better option is to keep the output datatype to some higher forms, like cv.CV_16S, cv.CV_64F etc, take its absolute value and then convert back to cv.CV_8U. Below code demonstrates this procedure for a horizontal Sobel filter and difference in results.</p>
<h2>Try it </h2>
<p> 
<iframe src="../../js_gradients_absSobel.html" width="100%"
        onload="this.style.height=this.contentDocument.body.scrollHeight +'px';">
</iframe>
 </p>
</div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:37 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
